package cn.bugDance.domain.strategy.service.rule.chain.impl;

import cn.bugDance.domain.activity.model.entity.ActivityAccountEntity;
import cn.bugDance.domain.activity.repository.IActivityRepository;
import cn.bugDance.domain.strategy.model.entity.RaffleFactorEntity;
import cn.bugDance.domain.strategy.model.entity.RuleConfigEntity;
import cn.bugDance.domain.strategy.model.valobj.StrategyConstant;
import cn.bugDance.domain.strategy.repository.IStrategyRepository;
import cn.bugDance.domain.strategy.service.dispatch.IRaffleStrategyDispatch;
import cn.bugDance.domain.strategy.service.rule.chain.AbstractRuleChain;
import cn.bugDance.domain.strategy.service.rule.chain.factory.RuleChainFactory;
import cn.bugDance.types.common.Constants;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;


import javax.annotation.Resource;
import java.util.*;

@Component(StrategyConstant.StrategyRule.RULE_WEIGHT)
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Slf4j
public class RuleWeightChain extends AbstractRuleChain {

    @Resource
    private IStrategyRepository strategyRepository;
    @Resource
    private IRaffleStrategyDispatch raffleStrategyDispatch;
    @Resource
    private IActivityRepository activityRepository;



    @Override
    public RuleChainFactory.RuleChainActionEntity action(RaffleFactorEntity raffleFactorEntity) {
        Long strategyId = raffleFactorEntity.getStrategyId();
        Long activityId = raffleFactorEntity.getActivityId();
        String userId = raffleFactorEntity.getUserId();

        log.info("【策略领域层-RuleWeightChain】: 开启权重责任链执行, strategyId: {}", strategyId);

        RuleConfigEntity ruleConfigEntity = strategyRepository.queryRuleConfigRule(strategyId, StrategyConstant.StrategyRule.RULE_WEIGHT);
        String config = ruleConfigEntity.getConfig();

        if(null != config){
            Set<Integer> levels = ruleConfigEntity.ruleConfigSplit().keySet();
            List<Integer> scores = new ArrayList<>(levels);


            // 逆序
            Comparator<Integer> comparator = (i1, i2) -> i2 - i1;
            scores.sort(comparator);

            ActivityAccountEntity activityAccountEntity = activityRepository.queryActivityAccountByUserIdAndActivityId(userId, activityId);
            Integer userScore;
            if(activityAccountEntity != null){
                userScore = activityAccountEntity.getTotalCount() - activityAccountEntity.getTotalCountSurplus();
            } else {
                userScore = 0;
            }

            Integer marchScore = scores.stream().filter(score -> score <= userScore).findFirst().orElse(null);

            // 用户所耗积分小于所有权重临界点值，采用最低权重范围进行抽奖
            Integer awardId = null;
            if(marchScore == null){
                Integer level = scores.get(scores.size() - 1);
                marchScore = level;
                awardId = raffleStrategyDispatch.randomRaffle(strategyId, level);
            }
            else{
                awardId = raffleStrategyDispatch.randomRaffle(strategyId, marchScore);
            }
            log.info("【策略领域层-RuleWeightChain】: 权重责任链拦截, strategyId: {}, awardId: {}, marchScore: {}", strategyId, awardId, marchScore);
            return RuleChainFactory.RuleChainActionEntity.builder()
                    .strategyId(strategyId)
                    .awardId(awardId).build();
        }

        log.info("【策略领域层-RuleWeightChain】: 权重责任链放行, strategyId: {}", strategyId);
        return this.getNext().action(raffleFactorEntity);
    }
}
